package com.ideal.frame.sys.service;

import com.ideal.frame.common.enumerate.ResponseCode;
import com.ideal.frame.config.security.JWTComponent;
import com.ideal.frame.excepion.BizException;
import com.ideal.frame.sys.dto.UserDto;
import com.ideal.frame.sys.dto.UserToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

/**
 * @Author: jin
 * @CreateTime: 2019-11-05 14:59
 * @Description: 用户认证
 */
@Service
public class AuthService {
    private final AuthenticationManager authenticationManager;
    @Autowired
    private SysUserService sysUserServices;
    @Autowired
    private JWTComponent jwtComponent;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    public AuthService(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    public UserToken login(String username, String password) {
        //用户验证
        final Authentication authentication = authenticate(username, password);
        //存储认证信息
        SecurityContextHolder.getContext().setAuthentication(authentication);
        //生成token
        final UserDto userDto = (UserDto) authentication.getPrincipal();
        final String token = jwtComponent.generateAccessToken(userDto);
        //存储token
        jwtComponent.putToken(username, token);
        return new UserToken(token, userDto);

    }


    public void logout(String token) {
        token = token.substring(tokenHead.length());
        String userName = jwtComponent.getUsernameFromToken(token);
        jwtComponent.deleteToken(userName);
    }


    public UserToken refresh(String oldToken) {
        String token = oldToken.substring(tokenHead.length());
        String username = jwtComponent.getUsernameFromToken(token);
        UserDto userDto = (UserDto) sysUserServices.loadUserByUsername(username);
        //TODO 判断是否可以刷新
        return null;
    }


    public UserDto getUserByToken(String token) {
        token = token.substring(tokenHead.length());
        UserDto user = jwtComponent.getUserFromToken(token);
        return (UserDto) sysUserServices.loadUserByUsername(user.getUsername());
    }

    private Authentication authenticate(String username, String password) {
        try {
            //该方法会去调用userDetailsService.loadUserByUsername()去验证用户名和密码，如果正确，则存储该用户名密码到“security 的 context中”
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (DisabledException | BadCredentialsException e) {
            throw new BizException(ResponseCode.AUTH_ERROR);
        }
    }
}
